package com.keyleaf.up.document.handler;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.IoUtil;
import com.keyleaf.up.document.model.OfficeConfig;
import lombok.extern.slf4j.Slf4j;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.local.LocalConverter;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * @author keyleaf
 * @since 2025/5/30
 **/
@Slf4j
public abstract class AbstractDocumentToPdfHandler {

    protected final OfficeConfig officeConfig;

    public AbstractDocumentToPdfHandler(OfficeConfig officeConfig) {
        this.officeConfig = officeConfig;
    }

    protected final List<String> supportedMimeTypes = new ArrayList<>();

    public boolean support(String mimeType) {
        return CollUtil.contains(supportedMimeTypes, mimeType);
    }

    /**
     * 文件转pdf
     * <p>
     * 这里之所以用Consumer方式而非直接返回InputStream是因为有的Handler可能会涉及到多个文件，
     * 用Consumer方式，可以将每个涉及到的文件转换后都会调用consume来处理
     * 比如针对目录的ToPdfHandler，会遍历目录下的所有文件
     * 比如针对压缩文件的ToPdfHandler，会先解压文件，然后遍历解压后的文件
     *
     * @param inputStream 待转换的文件流
     * @param consumer    消费转换后的pdf文件流
     */
    public void handle(InputStream inputStream, Consumer<InputStream> consumer) throws Exception {
        try (final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) {
            this.fetchBuilder().build().convert(inputStream).to(byteArrayOutputStream).as(DefaultDocumentFormatRegistry.PDF).execute();
            consumer.accept(new BufferedInputStream(IoUtil.toStream(byteArrayOutputStream)));
        }
    }

    private LocalConverter.Builder fetchBuilder() {
        Map<String, Object> customProperties = new HashMap<>();
        customProperties.put("FilterData", this.fetchFilterData());
        return LocalConverter.builder().storeProperties(customProperties);
    }

    private Map<String, Object> fetchFilterData() {
        Map<String, Object> filterData = new HashMap<>();
        filterData.put("EncryptFile", true);
//        filterData.put("PageRange", ConfigConstants.getOfficePageRange()); //限制页面
//        filterData.put("Watermark", ConfigConstants.getOfficeWatermark());  //水印
//        filterData.put("DocumentOpenPassword", fileAttribute.getFilePassword()); //给PDF添加密码

        //图片压缩
        filterData.put("Quality", officeConfig.getQuality());
        // DPI
        filterData.put("MaxImageResolution", officeConfig.getMaxImageResolution());
        // 导出书签
        filterData.put("ExportBookmarks", officeConfig.getExportBookmarks());
        // 批注作为PDF的注释
        filterData.put("ExportNotes", officeConfig.getExportNotes());
        return filterData;
    }
}
